package io.github.wanggit.antrpc.client.zk.zknode;

import io.github.wanggit.antrpc.commons.constants.ConstantValues;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/** 定期清理Zookeeper中的过期节点 */
@Slf4j
public final class ZkNodeCleaner implements IZkNodeCleaner, Runnable {

    private final ScheduledExecutorService executorService =
            Executors.newSingleThreadScheduledExecutor();
    private final IZkNodeOperator zkNodeOperator;

    public ZkNodeCleaner(IZkNodeOperator zkNodeOperator) {
        this.zkNodeOperator = zkNodeOperator;
        init();
    }

    private void init() {
        executorService.scheduleAtFixedRate(this, 1, 5, TimeUnit.MINUTES);
    }

    @Override
    public void run() {
        internalCleanUnusedNodes(ConstantValues.ZK_ROOT_SUBSCRIBE_NODE_NAME);
        internalCleanUnusedNodes(ConstantValues.ZK_ROOT_NODE_NAME);
        internalCleanUnusedNodes(ConstantValues.ZK_ROOT_NODE_UNREG_NAME);
    }

    @Override
    public void destory() {
        executorService.shutdown();
    }

    private void internalCleanUnusedNodes(String prefix) {
        String root = "/" + prefix;
        if (zkNodeOperator.existsNode(root)) {
            List<String> paths = zkNodeOperator.getChildren(root);
            if (null != paths && !paths.isEmpty()) {
                for (String path : paths) {
                    String subPath = "/" + prefix + "/" + path;
                    List<String> subNodes = zkNodeOperator.getChildren(subPath);
                    if (null == subNodes || subNodes.isEmpty()) {
                        zkNodeOperator.deleteNode(subPath);
                    }
                }
            }
        }
    }
}
